package brainfsck

import chisel3._
import chisel3.util._

class DataMemPort extends Bundle {
    val readValue   = Output(UInt(8.W))
    val writeEnable = Input(Bool())
    val shiftLeft   = Input(Bool())
    val shiftRight  = Input(Bool())
    val writeValue  = Input(UInt(8.W))
}

class DataMem(capacity: Int) extends Module {
    val io = IO(new DataMemPort)
    private val regs = Vector.fill(capacity)(RegInit(0.U(8.W)))

    private val regsShiftLeft  = regs.slice(1, capacity) ++ Vector(regs(0))
    private val regsShiftRight = Vector(regs.last) ++ regs.slice(0, capacity-1)

    regs(0) := Mux1H(Seq(
        io.writeEnable -> io.writeValue,
        io.shiftLeft   -> regs(1),
        io.shiftRight  -> regs(capacity-1),
        (!io.writeEnable && !io.shiftLeft && !io.shiftRight) -> regs(0),
    ))

    for (i <- 1 until capacity) {
        regs(i) := Mux1H(Seq(
            io.shiftLeft  -> regsShiftLeft(i),
            io.shiftRight -> regsShiftRight(i),
            (!io.shiftLeft && !io.shiftRight) -> regs(i),
        ))
    }

    io.readValue := regs(0)
}
